package com.example.utils;

import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.IOUtils;

import javax.servlet.http.HttpServletResponse;
import javax.swing.filechooser.FileSystemView;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author cc
 * @classname MinioUtil
 * @description TODO
 * @date 2022/6/26 13:53
 */
@Slf4j
public class MinioUtil {

    private static final String endpoint = "http://101.42.150.209:9000";    //对象存储服务的URL
    private static final String consoleUrl = "http://101.42.150.209:9001";    //控制台url
    private static final String accessKey = "admin";   //Access key就像用户ID，可以唯一标识你的账户
    private static final String secretKey = "password";   //Secret key是你账户的密码
    private static final String bucket = "bucket";   //桶
    private static final String separator = "/";    //分隔符

    /**
     * 上传对象
     *
     * @param objectPath
     * @return
     */
    public static String uploadObject(String objectPath) {
        //切割获取对象名称，可以指定名称
        String objectName = objectPath.substring(objectPath.lastIndexOf("\\") + 1);
        try {
            MinioClient minioClient = getMinioClient();
            // Make 'asiatrip' bucket if not exist.
            boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
            if (!found) {
                // Make a new bucket called 'asiatrip'.
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
            } else {
                System.out.println("Bucket '" + bucket + "' already exists.");
            }
            // Upload '/home/user/Photos/asiaphotos.zip' as object name 'asiaphotos-2015.zip' to bucket
            // 'asiatrip'.
            minioClient.uploadObject(
                    UploadObjectArgs.builder()
                            .bucket(bucket)
                            .object(objectName)  //命名名称
                            .filename(objectPath)   //文件路径
                            .build());
            System.out.println(
                    "【" + objectPath + "】 is successfully uploaded as "
                            + "object 【" + objectName + "】 to bucket 【" + bucket + "】");
        } catch (MinioException e) {
            System.out.println("Error occurred: " + e);
            System.out.println("HTTP trace: " + e.httpTrace());
        } catch (IOException | NoSuchAlgorithmException | InvalidKeyException e) {
            throw new RuntimeException(e);
        }
        return endpoint + separator + bucket + separator + objectName;
    }

    /**
     * 下载对象到桌面
     */
    public static void downloadLocal(String objectName) {
        String dowFilePath = FileSystemView.getFileSystemView().getHomeDirectory().getPath();   //下载存储路径-桌面
        try {
            MinioClient minioClient = getMinioClient();
            minioClient.downloadObject(
                    DownloadObjectArgs.builder()
                            .bucket(bucket)
                            .object(objectName)   //对象名称
                            .filename(dowFilePath + "/" + objectName) //文件路径
                            .build());
        } catch (ErrorResponseException | NoSuchAlgorithmException | InsufficientDataException | InternalException |
                 InvalidKeyException | InvalidResponseException | IOException | ServerException |
                 XmlParserException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 浏览器请求下载对象
     */
    public static void downloadObject(HttpServletResponse response, String objectName) {
        InputStream in = null;
        try {
            MinioClient minioClient = getMinioClient();
            StatObjectResponse stat = minioClient.statObject(StatObjectArgs.builder().bucket(bucket).object(objectName).build());
            response.setContentType(stat.contentType());
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(objectName, "UTF-8"));
            in = minioClient.getObject(GetObjectArgs.builder().bucket(bucket).object(objectName).build());
            IOUtils.copy(in, response.getOutputStream());
        } catch (ErrorResponseException | NoSuchAlgorithmException | InsufficientDataException | InternalException |
                 InvalidKeyException | InvalidResponseException | IOException | ServerException |
                 XmlParserException e) {
            throw new RuntimeException(e);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    log.error(e.getMessage());
                }
            }
        }
    }

    /**
     * 获取图片url，若是文件则下载
     *
     * @param objectName
     * @return
     */
    public static String getPreviewUrl(String objectName) {
        MinioClient minioClient = getMinioClient();

        // Get presigned URL string to download 'my-objectname' in 'my-bucketname'
        // with an expiration of 2 hours.
        //
        // Additionally also add 'response-content-type' to dynamically set content-type
        // for the server response.
        Map<String, String> reqParams = new HashMap<>();
        reqParams.put("response-content-type", "application/json");

        String url;
        try {
            url = minioClient.getPresignedObjectUrl(
                    GetPresignedObjectUrlArgs.builder()
                            .method(Method.GET)
                            .bucket(bucket)
                            .object(objectName)
                            //.expiry(2, TimeUnit.HOURS)  //设置过期时间
                            .extraQueryParams(reqParams)
                            .build());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return url.substring(0, url.indexOf("?"));
    }

    /**
     * 获取minio客户端
     *
     * @return
     */
    private static MinioClient getMinioClient() {
        // Create a minioClient with the MinIO server playground, its access key and secret key.
        return MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKey, secretKey)
                .build();
    }

}
